﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ling.P2P.Provider
{
    /// <summary>
    /// P2P 网路消息结构。
    /// </summary>
    public struct P2PMessage
    {
        /// <summary>
        /// 消息类型。
        /// </summary>
        public uint MessageType;
        /// <summary>
        /// 将要发送的内容长度
        /// </summary>
        public long ContentLength;
        /// <summary>
        /// 将要发送的内容分为多少次发送。
        /// </summary>
        public int SendSeveral;
        /// <summary>
        /// 每次发送多少字节。
        /// </summary>
        public int EachLength;

        /// <summary>
        /// 获取消息结构的字符长度。
        /// </summary>
        /// <returns></returns>
        public static int GetSize()
        {
            return sizeof(uint) + sizeof(long) + sizeof(int) * 2;
        }
    }

    /// <summary>
    /// 用于将 P2PMessage 在字节数组与结构之间进行转换的类。
    /// </summary>
    public static class P2PMessageConverter
    {
        /// <summary>
        /// 获得指定消息的字节数组。
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public static byte[] GetBytes(P2PMessage m)
        {
            int len = P2PMessage.GetSize(); // 计算数据的长度。
            byte[] data = new byte[len];
            byte[] buf = BitConverter.GetBytes(m.MessageType);
            int currentIndex = 0, i = 0;
            for (; i < buf.Length; ++i)
            {
                data[currentIndex] = buf[i];
                currentIndex++;
            }

            buf = BitConverter.GetBytes(m.ContentLength);
            for (i = 0; i < buf.Length; ++i)
            {
                data[currentIndex] = buf[i];
                currentIndex++;
            }

            buf = BitConverter.GetBytes(m.SendSeveral);
            for (i = 0; i < buf.Length; ++i)
            {
                data[currentIndex] = buf[i];
                currentIndex++;
            }

            buf = BitConverter.GetBytes(m.EachLength);
            for (i = 0; i < buf.Length; ++i)
            {
                data[currentIndex] = buf[i];
                currentIndex++;
            }

            return data;
        }

        /// <summary>
        /// 将指定的字节数组转换为 P2PMessage 结构。
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static P2PMessage GetMessage(byte[] data)
        {
            byte[] buf = new byte[sizeof(uint)];
            int dataIndex = 0;
            int i = 0;
            for (; i < buf.Length; ++i)
            {
                buf[i] = data[dataIndex];
                dataIndex++;
            }
            P2PMessage msg = new P2PMessage();
            msg.MessageType = BitConverter.ToUInt32(buf, 0);

            buf = null;
            buf = new byte[sizeof(int)];
            for (; i < buf.Length; ++i)
            {
                buf[i] = data[dataIndex];
                dataIndex++;
            }
            msg.ContentLength = BitConverter.ToInt64(data, 0);

            buf = null;
            buf = new byte[sizeof(int)];
            for (; i < buf.Length; ++i)
            {
                buf[i] = data[dataIndex];
                dataIndex++;
            }
            msg.SendSeveral = BitConverter.ToInt32(data, 0);

            buf = null;
            buf = new byte[sizeof(int)];
            for (; i < buf.Length; ++i)
            {
                buf[i] = data[dataIndex];
                dataIndex++;
            }
            msg.EachLength = BitConverter.ToInt32(data, 0);
            return msg;
        }
    }
}
